package proyecto0.src.directorio;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import TDAPair.*;

import java.util.*;

import proyectoX.src.TDAPair.Pair;

	public class Proyecto0 {
		
		protected static final int MAXIMO = 5;   //cantidad de entradas más frecuentes a tener en cuenta
		private int cantArchivos; //cantidad de archivos en el directorio
		private int cantTotal;  //usado para sacar el porcentaje al final
		private Pair<String, Integer> []ranking; 	
		protected java.util.Map<String, Integer> palabras;  
		
		
		public Proyecto0(){ 
			ranking= (Pair<String,Integer> [])new Pair[MAXIMO];
			cantTotal = 0;
			cantArchivos = 0;
			palabras = new java.util.HashMap<String, Integer>();
		}

		public void inicializarFichero(String p) throws InvalidPathException {
			File[] ficheros;
			File Rs = new File(p);
			ficheros = Rs.listFiles();
			if (ficheros == null) {
				throw new InvalidPathException();
			}
			cantArchivos=ficheros.length;
			for(int i=0;i<cantArchivos;i++){
				if (esTxt(ficheros[i].getName())) {  //sólo procesará archivos *.TXT
					insertarPalabra(p+"/"+ficheros[i].getName());
				}
			}

				
		}

		private void insertarPalabra(String string) {
			/* Este método recibe un string como paráetro que es el nombre del archivo,
			 *  Se lee el archivo y se ingresa al mapeo comparandolo con el top5 de entradas.
			 */
			try{
				String[]arr;
				String str;
				String palabra;
				FileReader fr= new FileReader(string);
				BufferedReader br= new BufferedReader(fr);
				boolean eof=false;
				while (!eof){
					str=br.readLine();
					if(str!=null){
						arr=str.split(" ");
						for(int i=0; i<arr.length;i++){
							if (!arr[i].equals("")) {
								palabra= RevisarString(arr[i]);
								Pair<String, Integer> c= new Pair<String, Integer>(palabra,null);//el valor lo agrega despues
								Integer aux;
								aux = palabras.get(palabra);								
								if(aux==null){
									aux=0;//no hay ninguna entrada con ese string como clave
								}
								c.setSecond(++aux);
								palabras.put(palabra,aux);
								cantTotal++;
								actualizarRanking(c.getFirst());
								}
							}
						}
					else eof=true;
					}				
			}catch(IOException e){System.out.println("A ocurrido un error en la lectura del archivo");}
			catch(IllegalArgumentException ex) { }
		}
		 
		
		private String RevisarString(String str){
			String nuevo= str.toLowerCase();
			int n=(int)nuevo.charAt(nuevo.length()-1);
			int pos=nuevo.length()-1;
			for(int i=0; i<2;i++){   
				if(!((n>47 &&n<58)||(96<n &&n<123)||(n==252 |n==235| n==228 | n==239|n==246)||(n==237 |n==243| n==250|n==225|n==233)))
				{	// revisa que el caracter representado por n sea letra, número, con acento, diéresis o ñ 
					nuevo=eliminarCaracter(nuevo,pos);
					str=nuevo;
				}
				if (!str.equals("")) { 
					n=(int)nuevo.charAt(0);
					pos=0;
				}
			} 
			return nuevo;
		}
		
		private String eliminarCaracter(String str, int pos) {
			String aDevolver="";
			if(pos==0)
			{
				for(int i=str.length()-1; i>0;i--)
					aDevolver=str.charAt(i)+aDevolver;
				}
			else
			{
				for(int i=0; i<str.length()-1;i++)
					aDevolver=aDevolver+str.charAt(i);
				}
			return aDevolver;
			 }
		
				
		//devuelve el porcentaje sobre el total de palabras que le corresponde a la palabra de la entrada
		private float porcentaje(Pair<String, Integer> e) {
		    int valor = e.getSecond();
		    float resultado;
		    if (cantTotal != 0) {
		    	resultado = ((valor*100)/cantTotal); 
		    }
		    else {
		    	resultado = -100f; //devuelve esto si no hay palabras almacenadas 
		    }
		    return resultado;
		}


		//arreglo ordenado de menor a mayor, la palabra más frecuente corresponde a la almacenada en la celda de mayor índice (4)
		public String[] palabrasMasFrecuentes() {
		    String[] resultado = new String[ranking.length];
		    int i;
		    for (i = ranking.length-1; (i >= 0)&&(ranking[i] != null); i--) {
			  Pair<String, Integer> e = ranking[i];
			  String palabra = e.getFirst();
			  int frecuencia = e.getSecond();
			  resultado[i] = palabra+", "+frecuencia+", "+porcentaje(ranking[i])+"%";
		    }
		    return resultado;
		}


		//determina si la palabra de la entrada pasada por parámetro corresponde a una de las (5) palabras más frecuentes
		private void actualizarRanking(String str) {
			try {
				//hallo posición a insertar para la nueva entrada (se mantiene en -1 si no hay que insertarlo en la tabla)
				int posicionAInsertar = -1;
				boolean cortar = false;

				for (int i = 0; (i < ranking.length)&&(!cortar); i++) { //probar insertar con celdas en nulo
					if (ranking[i] != null) {
						if  ((ranking[i].getSecond() > palabras.get(str))) {  //&&(!ranking[i].getFirst().equals(str))  
							cortar = true;
							posicionAInsertar = i-1;
						}
						else {
							if (ranking[i].getFirst().equals(str)) {  //si encuentra la misma
								ranking[i].setSecond(palabras.get(str));
								for (int k = i+1; k < ranking.length; k++) {  //o es el último, o tiene vecinos derechos (no necesariamente izquierdos)
									if  ((ranking[k].getSecond() <= palabras.get(str))) {
										Pair<String, Integer> aux = ranking[k-1];
										ranking[k-1] = ranking[k];
										ranking[k] = aux;
									}
								}
								cortar = true; //no se debe insertar cuando actualizamos una palabra que ya se encuentra en el ranking
								posicionAInsertar = -1; 
							}
							else {
								if (ranking[i].getSecond() < palabras.get(str)) {
									posicionAInsertar = i;
								}
							}
						}
					}
					else {
						posicionAInsertar = i;
					}
				}


				//si hay que insertar, inserta en la celda correspondiente y desplaza los contenidos hacia la izquierda
				if (posicionAInsertar >= 0) {

					for (int k = 0; k < posicionAInsertar; k++) {  //desplazamiento a izquierda a menos que se llegue al final del arreglo
						ranking[k] = ranking[k+1];
					}
					ranking[posicionAInsertar] = new Pair<String, Integer>(str, palabras.get(str));
				}
			}
			catch(IllegalArgumentException ex) {
				System.out.println("Se ha ingresado una clave nula!");
			}
		}
		
		private boolean esTxt(String ruta) {
			boolean resultado = false;
			int longitud = ruta.length();
			if (longitud >= 4) {
				resultado = ruta.substring(longitud-4).equals(".txt");
			}
			return resultado;
		}
	}
	


